#include "contacts.pb.h"
#include <iostream>
#include <fstream>
#include <google/protobuf/unknown_field_set.h>
using namespace std;

void PrintContacts(const r_contacts::Contacts &contacts)
{
    for (int i = 0; i < contacts.people_size(); i++)
    {
        const r_contacts::PeopleInfo &peopleinfo = contacts.people(i); // 通过下标获取people
        std::cout << "----------联系人" << i + 1 << "----------" << std::endl;
        std::cout << "联系人姓名： " << peopleinfo.name() << std::endl;
        std::cout << "联系人年龄： " << peopleinfo.age() << std::endl;
        int j = 1;
        for (; j <= peopleinfo.phone_size(); j++)
        {
            std::cout << "电话： " << peopleinfo.phone(j - 1).number();
            r_contacts::Phone phone = peopleinfo.phone(j - 1);
            std::cout << "  类型[" << phone.type() << "]" << std::endl;
        }
        // 如果有address成员，并且address成员的类型是Address
        if (peopleinfo.has_address() && peopleinfo.address().Is<r_contacts::Address>())
        {
            r_contacts::Address address;
            peopleinfo.address().UnpackTo(&address);
            if (!address.home_address().empty())
            {
                std::cout << "家庭地址：" << address.home_address() << std::endl;
            }

            if (!address.unit_address().empty())
            {
                std::cout << "单位地址：" << address.unit_address() << std::endl;
            }
        }

        /*
            第一种写法
        if (people.has_qq()) {

        } else if (people.has_weixin()) {

        } */

        // 写法二
        switch (peopleinfo.gender_case())
        {
        case r_contacts::PeopleInfo::kMale:
            std::cout << "性别：male" << std::endl;
            break;
        case r_contacts::PeopleInfo::kFemale:
            std::cout << "性别：female" << std::endl;
            break;
        case r_contacts::PeopleInfo::GENDER_NOT_SET:
            std::cout << "性别：未设置" << std::endl;
            break;
        default:
            std::cout << "未知错误! " << std::endl;
            break;
        }

        // 打印备注
        if (peopleinfo.remarks_size())
        {
            for (auto it = peopleinfo.remarks().cbegin(); it != peopleinfo.remarks().end(); it++)
            {
                std::cout << " " << it->first << ": " << it->second << std::endl;
            }
        }


        /*
            打印未知字段
        */
        const google::protobuf::Reflection *reflect = r_contacts::PeopleInfo::GetReflection(); // 获取未知字段
        const google::protobuf::UnknownFieldSet &unknowset = reflect->GetUnknownFields(peopleinfo);
        for (int j = 0; j < unknowset.field_count(); j++)
        {
            const google::protobuf::UnknownField &unknow_field = unknowset.field(j);
            cout << "未知字段" << j + 1 << ":"
                 << " 字段编号: " << unknow_field.number()
                 << " 类型: " << unknow_field.type();
            switch (unknow_field.type())
            {
            case google::protobuf::UnknownField::Type::TYPE_VARINT:
                cout << " 值: " << unknow_field.varint() << endl;
                break;
            case google::protobuf::UnknownField::Type::TYPE_LENGTH_DELIMITED:
                cout << " 值: " << unknow_field.length_delimited() << endl;
                break;
            }
        }
    }
}

int main()
{
    r_contacts::Contacts contacts;
    fstream input("../contacts.bin", ios::binary | ios::in);
    if (!input)
    {
        std::cout << " contacts.bin not find,create new file! " << std::endl;
    }
    else if (!contacts.ParseFromIstream(&input))
    {

        std::cerr << " Failed to Parse contacts.bin !" << std::endl;
        input.close();
        return -1;
    }
    PrintContacts(contacts);
    input.close();
    google::protobuf::ShutdownProtobufLibrary();
    return 0;
}
